from sqlalchemy import Result, select
from sqlalchemy.ext.asyncio import AsyncSession

from price_analysis.core.models import IncomingSO
from . import schemas


async def check_exists(session: AsyncSession, file_name: str) -> int | None:
    stmt = select(IncomingSO).where(IncomingSO.file_name == file_name)
    result: Result = await session.execute(stmt)
    checked_item: IncomingSO = result.scalars().first()
    if checked_item:
        return checked_item.id

    return None


async def create_incoming_so(session: AsyncSession, file_name: str) -> int:
    item: int = await check_exists(session, file_name)

    if item is not None:
        return item

    incoming_so = IncomingSO(file_name=file_name)
    session.add(incoming_so)
    await session.commit()
    await session.refresh(incoming_so)

    return incoming_so.id


async def get_incoming_so(session: AsyncSession, idx: int) -> IncomingSO:
    stmt = select(IncomingSO).where(IncomingSO.id == idx)
    result: Result = await session.execute(stmt)
    incoming_so: IncomingSO = result.scalar_one()
    return incoming_so


async def get_all_incoming_so(session: AsyncSession) -> list[IncomingSO]:
    stmt = select(IncomingSO).order_by(IncomingSO.id)
    result: Result = await session.execute(stmt)
    in_data = result.scalars().all()
    return list(in_data)


async def delete_incoming_so(session: AsyncSession,
                             incoming_so: IncomingSO) -> dict[str, bool]:
    await session.delete(incoming_so)
    await session.commit()

    return {"result": True}


async def update_incoming_so(
    session: AsyncSession,
    incoming_so: IncomingSO,
    so_update: schemas.IncomingSoUpdate | schemas.IncomingSoUpdatePartial,
    partial: bool = False,
) -> IncomingSO:
    for name, value in so_update.model_dump(exclude_unset=partial).items():
        setattr(incoming_so, name, value)
    await session.commit()

    return incoming_so
